home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Library / sound.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  7KB  |  280 lines

  1. /*
  2.  * sound.c  V3.1
  3.  *
  4.  * ToolManager Objects Sound class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Local data */
  19. #define PROPCHUNKS 2
  20. static const ULONG PropChunkTable[2 * PROPCHUNKS] = {
  21.  ID_TMSO, ID_CMND,
  22.  ID_TMSO, ID_PORT
  23. };
  24.  
  25. /* Sound class instance data */
  26. struct SoundClassData {
  27.  char  *scd_Command;
  28. };
  29. #define TYPED_INST_DATA(cl, o) ((struct SoundClassData *) INST_DATA((cl), (o)))
  30.  
  31. /* Create ARexx command */
  32. #define DEBUGFUNCTION CreateSoundCommand
  33. static char *CreateSoundCommand(char *cmd, ULONG len, char *port)
  34. {
  35.  char *rc = NULL;
  36.  
  37.  SOUNDCLASS_LOG(LOG3(Entry, "Command '%s' (%ld) Port '%s'", cmd, len, port))
  38.  
  39.  /* Port valid? No, set default port */
  40.  if (port == NULL) port = "PLAY";
  41.  
  42.  /* Calculate ARexx command string length */
  43.  /* + 10   for "'address \""              */
  44.  /* + 3    for "\" \""                    */
  45.  /* + 2    for "\"'"                      */
  46.  /* + length of port name                 */
  47.  len += 15 + strlen(port);
  48.  
  49.  /* Allocate memory for command string (plus string terminator!) */
  50.  if (rc = GetVector(len + 1)) {
  51.   char *s = rc;
  52.  
  53.   /* Build command line */
  54.   strcpy(s, "'address \""); s += 10;
  55.   strcpy(s, port);          s += strlen(s);
  56.   strcpy(s, "\" \"");       s += 3;
  57.   strcpy(s, cmd);           s += strlen(s);
  58.   strcpy(s, "\"'");
  59.  
  60.   SOUNDCLASS_LOG(LOG3(ARexx Cmd, "%s (0x%08lx, %ld)", rc, rc, len))
  61.  }
  62.  
  63.  SOUNDCLASS_LOG(LOG1(Result, "0x%08lx", rc))
  64.  
  65.  return(rc);
  66. }
  67.  
  68. /* Sound class method: OM_NEW */
  69. #undef  DEBUGFUNCTION
  70. #define DEBUGFUNCTION SoundClassNew
  71. static ULONG SoundClassNew(Class *cl, Object *obj, struct opSet *ops)
  72. {
  73.  SOUNDCLASS_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  74.                  PrintTagList(ops->ops_AttrList)))
  75.  
  76.  /* Call SuperClass */
  77.  if (obj = (Object *) DoSuperMethodA(cl, obj, (Msg) ops)) {
  78.   struct SoundClassData *scd = TYPED_INST_DATA(cl, obj);
  79.  
  80.   /* Initialize instance data */
  81.   scd->scd_Command = NULL;
  82.  }
  83.  
  84.  return((ULONG) obj);
  85. }
  86.  
  87. /* Sound class method: OM_DISPOSE */
  88. #undef  DEBUGFUNCTION
  89. #define DEBUGFUNCTION SoundClassDispose
  90. static ULONG SoundClassDispose(Class *cl, Object *obj, Msg msg)
  91. {
  92.  struct SoundClassData *scd = TYPED_INST_DATA(cl, obj);
  93.  
  94.  SOUNDCLASS_LOG(LOG0(Disposing))
  95.  
  96.  /* Free command string */
  97.  if (scd->scd_Command) FreeVector(scd->scd_Command);
  98.  
  99.  /* Call SuperClass */
  100.  return(DoSuperMethodA(cl, obj, msg));
  101. }
  102.  
  103. /* Sound class method: TMM_ParseIFF */
  104. #undef  DEBUGFUNCTION
  105. #define DEBUGFUNCTION SoundClassParseIFF
  106. static ULONG SoundClassParseIFF(Class *cl, Object *obj,
  107.                                 struct TMP_ParseIFF *tmppi)
  108. {
  109.  BOOL rc = FALSE;
  110.  
  111.  SOUNDCLASS_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  112.  
  113.  /* Initialize IFF parser and forward method to SuperClass */
  114.  if ((PropChunks(tmppi->tmppi_IFFHandle, PropChunkTable, PROPCHUNKS) == 0) &&
  115.      DoSuperMethodA(cl, obj, (Msg) tmppi)) {
  116.   struct StoredProperty *cmnd;
  117.  
  118.   SOUNDCLASS_LOG(LOG0(FORM TMSO chunk parsed OK))
  119.  
  120.   /* Check for mandatory CMND property */
  121.   if (cmnd = FindProp(tmppi->tmppi_IFFHandle, ID_TMSO, ID_CMND)) {
  122.    struct StoredProperty *sp;
  123.  
  124.    SOUNDCLASS_LOG(LOG2(Command, "'%s' (%ld)", cmnd->sp_Data, cmnd->sp_Size))
  125.  
  126.    /* Find PORT property */
  127.    sp = FindProp(tmppi->tmppi_IFFHandle, ID_TMSO, ID_PORT);
  128.  
  129.    /* Create sound command string */
  130.    if (TYPED_INST_DATA(cl, obj)->scd_Command =
  131.         CreateSoundCommand(cmnd->sp_Data, cmnd->sp_Size - 1,
  132.                            sp ? sp->sp_Data : NULL))
  133.  
  134.     /* Configuration data parsed */
  135.     rc = TRUE;
  136.   }
  137.  }
  138.  
  139.  SOUNDCLASS_LOG(LOG1(Result, "%ld", rc))
  140.  
  141.  return(rc);
  142. }
  143.  
  144. /* Sound class method: TMM_ParseTags */
  145. #undef  DEBUGFUNCTION
  146. #define DEBUGFUNCTION SoundClassParseTags
  147. static ULONG SoundClassParseTags(Class *cl, Object *obj,
  148.                                  struct TMP_ParseTags *tmppt)
  149. {
  150.  struct SoundClassData *scd    = TYPED_INST_DATA(cl, obj);
  151.  struct TagItem        *tstate = tmppt->tmppt_Tags;
  152.  struct TagItem        *ti;
  153.  char                  *cmd;
  154.  char                  *port;
  155.  BOOL                   rc     = TRUE;
  156.  
  157.  SOUNDCLASS_LOG((LOG1(Tags, "0x%08lx", tmppt->tmppt_Tags),
  158.                 PrintTagList(tmppt->tmppt_Tags)))
  159.  
  160.  /* Free old command */
  161.  if (scd->scd_Command) FreeVector(scd->scd_Command);
  162.  
  163.  /* Scan tag list */
  164.  while (rc && (ti = NextTagItem(&tstate)))
  165.  
  166.   /* Which tag? */
  167.   switch (ti->ti_Tag) {
  168.    case TMOP_Command:
  169.     if (ti->ti_Data)
  170.  
  171.      cmd = (char *) ti->ti_Data;
  172.  
  173.     else
  174.  
  175.      rc = FALSE;
  176.  
  177.     break;
  178.  
  179.    case TMOP_Port:
  180.     port = (char *) ti->ti_Data;
  181.     break;
  182.   }
  183.  
  184.  /* No error? */
  185.  if (rc)
  186.  
  187.   /* Yes, create new command */
  188.   rc = (scd->scd_Command = CreateSoundCommand(cmd, strlen(cmd), port)) != NULL;
  189.  
  190.  else
  191.  
  192.   /* Clear command pointer */
  193.   scd->scd_Command = NULL;
  194.  
  195.  SOUNDCLASS_LOG(LOG1(Result, "%ld", rc))
  196.  
  197.  return(rc);
  198. }
  199.  
  200. /* Sound class method: TMM_Activate */
  201. #undef  DEBUGFUNCTION
  202. #define DEBUGFUNCTION SoundClassActivate
  203. static ULONG SoundClassActivate(Class *cl, Object *obj)
  204. {
  205.  struct SoundClassData *scd = TYPED_INST_DATA(cl, obj);
  206.  
  207.  SOUNDCLASS_LOG(LOG0(Entry))
  208.  
  209.  /* Send ARexx command */
  210.  if (scd->scd_Command) SendARexxCommand(scd->scd_Command,
  211.                                         strlen(scd->scd_Command));
  212.  
  213.  /* Return 1 to indicate that the method is implemented */
  214.  return(1);
  215. }
  216.  
  217. /* Sound class dispatcher */
  218. #undef  DEBUGFUNCTION
  219. #define DEBUGFUNCTION SoundClassDispatcher
  220. static __geta4 ULONG SoundClassDispatcher(__A0 Class *cl, __A2 Object *obj,
  221.                                           __A1 Msg msg)
  222. {
  223.  ULONG rc;
  224.  
  225.  SOUNDCLASS_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  226.                      cl, obj, msg))
  227.  
  228.  switch(msg->MethodID) {
  229.   /* BOOPSI methods */
  230.   case OM_NEW:
  231.    rc = SoundClassNew(cl, obj, (struct opSet *) msg);
  232.    break;
  233.  
  234.   case OM_DISPOSE:
  235.    rc = SoundClassDispose(cl, obj, msg);
  236.    break;
  237.  
  238.   /* TM methods */
  239.   case TMM_ParseIFF:
  240.    rc = SoundClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  241.    break;
  242.  
  243.   case TMM_ParseTags:
  244.    rc = SoundClassParseTags(cl, obj, (struct TMP_ParseTags *) msg);
  245.    break;
  246.  
  247.   case TMM_Activate:
  248.    rc = SoundClassActivate(cl, obj);
  249.    break;
  250.  
  251.   /* Unknown method -> delegate to SuperClass */
  252.   default:
  253.    rc = DoSuperMethodA(cl, obj, msg);
  254.    break;
  255.  }
  256.  
  257.  return(rc);
  258. }
  259.  
  260. /* Create Sound class */
  261. #undef  DEBUGFUNCTION
  262. #define DEBUGFUNCTION CreateSoundClass
  263. Class *CreateSoundClass(Class *superclass)
  264. {
  265.  Class *cl;
  266.  
  267.  SOUNDCLASS_LOG(LOG1(SuperClass, "0x%08lx", superclass))
  268.  
  269.  /* Create class */
  270.  if (cl = MakeClass(NULL, NULL, superclass, sizeof(struct SoundClassData), 0))
  271.  
  272.   /* Set dispatcher */
  273.   cl->cl_Dispatcher.h_Entry = (ULONG (*)()) SoundClassDispatcher;
  274.  
  275.  SOUNDCLASS_LOG(LOG1(Class, "0x%08lx", cl))
  276.  
  277.  /* Return pointer to class */
  278.  return(cl);
  279. }
  280.